/*
 * GL_Render_Shape.h
 *
 * Created 6/2/2009 By Johnny Huynh
 *
 * Version 00.00.01 6/2/2009
 *
 * Copyright Information:
 * All content copyright © 2009 Johnny Huynh. All rights reserved.
 */

 #ifndef RENDER_SHAPE_H
 #define RENDER_SHAPE_H

 #include "Vector3.h"
 #include "OrientationMatrix.h"

 // Contains functions for rendering common shapes in OpenGL
 namespace Render_Shape 
 {
    template <typename TYPENAME> inline void setColor( TYPENAME red, TYPENAME green, TYPENAME blue );
    template <typename TYPENAME> inline void Triangle_Solid( const Vector3<TYPENAME>& a, 
                                                             const Vector3<TYPENAME>& b, const Vector3<TYPENAME>& c );
    template <typename TYPENAME> inline void Triangle_WireFrame( const Vector3<TYPENAME>& a, 
                                                                 const Vector3<TYPENAME>& b, const Vector3<TYPENAME>& c );
    template <typename TYPENAME> inline void Box_Solid( const Vector3<TYPENAME>& center, 
                                 const Vector3<TYPENAME>& halfDimensions, OrientationMatrix3<TYPENAME> orientation );
    template <typename TYPENAME> inline void Box_WireFrame( const Vector3<TYPENAME>& center, 
                                 const Vector3<TYPENAME>& halfDimensions, OrientationMatrix3<TYPENAME> orientation );
    template <typename TYPENAME> inline void Box_WireFrame( const Vector3<TYPENAME>& center, 
                                 const TYPENAME& half_width, const TYPENAME& half_height, const TYPENAME& half_depth,
                                 TYPENAME Xx, TYPENAME Yx, TYPENAME Zx,
                                 TYPENAME Xy, TYPENAME Yy, TYPENAME Zy,
                                 TYPENAME Xz, TYPENAME Yz, TYPENAME Zz );
    template <typename TYPENAME> inline void Sphere_WireFrame( const Vector3<TYPENAME>& center, const TYPENAME radius );
 }
 
 /**
  * setColor() sets the drawing color for the Graphics API. The values set for each
  * of the color should be between 0 and 1.
  *
  * @param (TYPENAME) red
  * @param (TYPENAME) green
  * @param (TYPENAME) blue
  */
 template <typename TYPENAME>
 inline void Render_Shape::setColor( TYPENAME red, TYPENAME green, TYPENAME blue )
 {
    glColor3f( red, green, blue );
 }
 
 /**
  * Triangle_Solid() renders a solid triangle given the three points of the triangle winding counter-clockwise.
  *
  * @param (const Vector3<TYPENAME>&) a - vertex A of the triangle
  * @param (const Vector3<TYPENAME>&) b - vertex B of the triangle
  * @param (const Vector3<TYPENAME>&) c - vertex C of the triangle
  */
 template <typename TYPENAME>
 inline void Render_Shape::Triangle_Solid( const Vector3<TYPENAME>& a, const Vector3<TYPENAME>& b, 
                                           const Vector3<TYPENAME>& c )
 {
	Vector3f norm( normal( GL_Trianglef( a, b, c ) ) );
    glBegin( GL_TRIANGLES );
		glNormal3f( norm.x, norm.y, norm.z );	// must specify the normal for OpenGL lighting purposes
        glVertex3f( a.x, a.y, a.z );
        glVertex3f( b.x, b.y, b.z );
        glVertex3f( c.x, c.y, c.z );
    glEnd();
 }
 
 /**
  * Triangle_WireFrame() renders a wire frame triangle given the three points of the triangle.
  *
  * @param (const Vector3<TYPENAME>&) a - vertex A of the triangle
  * @param (const Vector3<TYPENAME>&) b - vertex B of the triangle
  * @param (const Vector3<TYPENAME>&) c - vertex C of the triangle
  */
 template <typename TYPENAME> 
 inline void Render_Shape::Triangle_WireFrame( const Vector3<TYPENAME>& a, 
                                               const Vector3<TYPENAME>& b, const Vector3<TYPENAME>& c )
 {
    glBegin( GL_LINE_LOOP );
        glVertex3f( a.x, a.y, a.z );
        glVertex3f( b.x, b.y, b.z );
        glVertex3f( c.x, c.y, c.z ); 
    glEnd();
 }
 
 /**
  * Box_Solid() renders a solid box given the center of the box, the half-dimensions of the box (i.e. the dimensions
  * of the box divided by two), and the orientation of the box (i.e. the x-axis, y-axis, and z-axis of the box).
  *
  * @param (const Vector3<TYPENAME>&) center
  * @param (const Vector3<TYPENAME>&) halfDimensions
  * @param (OrientationMatrix<TYPENAME>) orientation
  */
 template <typename TYPENAME> 
 inline void Render_Shape::Box_Solid( const Vector3<TYPENAME>& center, const Vector3<TYPENAME>& halfDimensions, 
                                     OrientationMatrix3<TYPENAME> orientation )
 {
    orientation.Xx *= halfDimensions.x;
    orientation.Xy *= halfDimensions.x;
    orientation.Xz *= halfDimensions.x;
    orientation.Yx *= halfDimensions.y;
    orientation.Yy *= halfDimensions.y;
    orientation.Yz *= halfDimensions.y;
    orientation.Zx *= halfDimensions.z;
    orientation.Zy *= halfDimensions.z;
    orientation.Zz *= halfDimensions.z;
    
    // Draw the rectangle
    
    // Front Face
    glBegin( GL_QUADS );
        glVertex3f( center.x + orientation.Xx + orientation.Yx + orientation.Zx, 
                    center.y + orientation.Xy + orientation.Yy + orientation.Zy, 
                    center.z + orientation.Xz + orientation.Yz + orientation.Zz);
        glVertex3f( center.x - orientation.Xx + orientation.Yx + orientation.Zx, 
                    center.y - orientation.Xy + orientation.Yy + orientation.Zy, 
                    center.z - orientation.Xz + orientation.Yz + orientation.Zz);
        glVertex3f( center.x - orientation.Xx - orientation.Yx + orientation.Zx, 
                    center.y - orientation.Xy - orientation.Yy + orientation.Zy, 
                    center.z - orientation.Xz - orientation.Yz + orientation.Zz);
        glVertex3f( center.x + orientation.Xx - orientation.Yx + orientation.Zx, 
                    center.y + orientation.Xy - orientation.Yy + orientation.Zy, 
                    center.z + orientation.Xz - orientation.Yz + orientation.Zz);
    glEnd();

    // Top Face
    glBegin( GL_QUADS );
        glVertex3f( center.x + orientation.Xx + orientation.Yx + orientation.Zx, 
                    center.y + orientation.Xy + orientation.Yy + orientation.Zy, 
                    center.z + orientation.Xz + orientation.Yz + orientation.Zz);
        glVertex3f( center.x + orientation.Xx + orientation.Yx - orientation.Zx, 
                    center.y + orientation.Xy + orientation.Yy - orientation.Zy, 
                    center.z + orientation.Xz + orientation.Yz - orientation.Zz);
        glVertex3f( center.x - orientation.Xx + orientation.Yx - orientation.Zx, 
                    center.y - orientation.Xy + orientation.Yy - orientation.Zy, 
                    center.z - orientation.Xz + orientation.Yz - orientation.Zz);
        glVertex3f( center.x - orientation.Xx + orientation.Yx + orientation.Zx, 
                    center.y - orientation.Xy + orientation.Yy + orientation.Zy, 
                    center.z - orientation.Xz + orientation.Yz + orientation.Zz);
    glEnd();
    
    // Back Face
    glBegin( GL_QUADS );
        glVertex3f( center.x - orientation.Xx + orientation.Yx - orientation.Zx, 
                    center.y - orientation.Xy + orientation.Yy - orientation.Zy, 
                    center.z - orientation.Xz + orientation.Yz - orientation.Zz);
        glVertex3f( center.x + orientation.Xx + orientation.Yx - orientation.Zx, 
                    center.y + orientation.Xy + orientation.Yy - orientation.Zy, 
                    center.z + orientation.Xz + orientation.Yz - orientation.Zz);
        glVertex3f( center.x + orientation.Xx - orientation.Yx - orientation.Zx, 
                    center.y + orientation.Xy - orientation.Yy - orientation.Zy, 
                    center.z + orientation.Xz - orientation.Yz - orientation.Zz);
        glVertex3f( center.x - orientation.Xx - orientation.Yx - orientation.Zx, 
                    center.y - orientation.Xy - orientation.Yy - orientation.Zy, 
                    center.z - orientation.Xz - orientation.Yz - orientation.Zz);
    glEnd();
    
    // Bottom Face
    glBegin( GL_QUADS );
        glVertex3f( center.x + orientation.Xx - orientation.Yx - orientation.Zx, 
                    center.y + orientation.Xy - orientation.Yy - orientation.Zy, 
                    center.z + orientation.Xz - orientation.Yz - orientation.Zz);
        glVertex3f( center.x + orientation.Xx - orientation.Yx + orientation.Zx, 
                    center.y + orientation.Xy - orientation.Yy + orientation.Zy, 
                    center.z + orientation.Xz - orientation.Yz + orientation.Zz);
        glVertex3f( center.x - orientation.Xx - orientation.Yx + orientation.Zx, 
                    center.y - orientation.Xy - orientation.Yy + orientation.Zy, 
                    center.z - orientation.Xz - orientation.Yz + orientation.Zz);
        glVertex3f( center.x - orientation.Xx - orientation.Yx - orientation.Zx, 
                    center.y - orientation.Xy - orientation.Yy - orientation.Zy, 
                    center.z - orientation.Xz - orientation.Yz - orientation.Zz);
    glEnd();
    
    // Left Face
    glBegin( GL_QUADS );
        glVertex3f( center.x - orientation.Xx + orientation.Yx + orientation.Zx, 
                    center.y - orientation.Xy + orientation.Yy + orientation.Zy, 
                    center.z - orientation.Xz + orientation.Yz + orientation.Zz);
        glVertex3f( center.x - orientation.Xx + orientation.Yx - orientation.Zx, 
                    center.y - orientation.Xy + orientation.Yy - orientation.Zy, 
                    center.z - orientation.Xz + orientation.Yz - orientation.Zz);
        glVertex3f( center.x - orientation.Xx - orientation.Yx - orientation.Zx, 
                    center.y - orientation.Xy - orientation.Yy - orientation.Zy, 
                    center.z - orientation.Xz - orientation.Yz - orientation.Zz);
        glVertex3f( center.x - orientation.Xx - orientation.Yx + orientation.Zx, 
                    center.y - orientation.Xy - orientation.Yy + orientation.Zy, 
                    center.z - orientation.Xz - orientation.Yz + orientation.Zz);
    glEnd();

    // Right Face
    glBegin( GL_QUADS );
        glVertex3f( center.x + orientation.Xx + orientation.Yx - orientation.Zx, 
                    center.y + orientation.Xy + orientation.Yy - orientation.Zy, 
                    center.z + orientation.Xz + orientation.Yz - orientation.Zz);
        glVertex3f( center.x + orientation.Xx + orientation.Yx + orientation.Zx, 
                    center.y + orientation.Xy + orientation.Yy + orientation.Zy, 
                    center.z + orientation.Xz + orientation.Yz + orientation.Zz);
        glVertex3f( center.x + orientation.Xx - orientation.Yx + orientation.Zx, 
                    center.y + orientation.Xy - orientation.Yy + orientation.Zy, 
                    center.z + orientation.Xz - orientation.Yz + orientation.Zz);
        glVertex3f( center.x + orientation.Xx - orientation.Yx - orientation.Zx, 
                    center.y + orientation.Xy - orientation.Yy - orientation.Zy, 
                    center.z + orientation.Xz - orientation.Yz - orientation.Zz);
    glEnd();
    // End of draw rectangle
 }

 /**
  * Box_WireFrame() renders a wire frame box given the center of the box, the half-dimensions of the box (i.e. the dimensions
  * of the box divided by two), and the orientation of the box (i.e. the x-axis, y-axis, and z-axis of the box).
  *
  * @param (const Vector3<TYPENAME>&) center
  * @param (const Vector3<TYPENAME>&) halfDimensions
  * @param (OrientationMatrix<TYPENAME>) orientation
  */
 template <typename TYPENAME>
 inline void Render_Shape::Box_WireFrame( const Vector3<TYPENAME>& center, const Vector3<TYPENAME>& halfDimensions, 
                                OrientationMatrix3<TYPENAME> orientation )
 {
    orientation.Xx *= halfDimensions.x;
    orientation.Xy *= halfDimensions.x;
    orientation.Xz *= halfDimensions.x;
    orientation.Yx *= halfDimensions.y;
    orientation.Yy *= halfDimensions.y;
    orientation.Yz *= halfDimensions.y;
    orientation.Zx *= halfDimensions.z;
    orientation.Zy *= halfDimensions.z;
    orientation.Zz *= halfDimensions.z;
    
    // Draw wireframe box
    
    // Top Face
    glBegin( GL_LINES );
        glVertex3f( center.x + orientation.Xx + orientation.Yx + orientation.Zx, 
                    center.y + orientation.Xy + orientation.Yy + orientation.Zy, 
                    center.z + orientation.Xz + orientation.Yz + orientation.Zz );
        glVertex3f( center.x + orientation.Xx + orientation.Yx - orientation.Zx, 
                    center.y + orientation.Xy + orientation.Yy - orientation.Zy, 
                    center.z + orientation.Xz + orientation.Yz - orientation.Zz );
        glVertex3f( center.x + orientation.Xx + orientation.Yx - orientation.Zx, 
                    center.y + orientation.Xy + orientation.Yy - orientation.Zy, 
                    center.z + orientation.Xz + orientation.Yz - orientation.Zz );
        glVertex3f( center.x - orientation.Xx + orientation.Yx - orientation.Zx, 
                    center.y - orientation.Xy + orientation.Yy - orientation.Zy, 
                    center.z - orientation.Xz + orientation.Yz - orientation.Zz );
        glVertex3f( center.x - orientation.Xx + orientation.Yx - orientation.Zx, 
                    center.y - orientation.Xy + orientation.Yy - orientation.Zy, 
                    center.z - orientation.Xz + orientation.Yz - orientation.Zz );
        glVertex3f( center.x - orientation.Xx + orientation.Yx + orientation.Zx, 
                    center.y - orientation.Xy + orientation.Yy + orientation.Zy, 
                    center.z - orientation.Xz + orientation.Yz + orientation.Zz );
        glVertex3f( center.x - orientation.Xx + orientation.Yx + orientation.Zx, 
                    center.y - orientation.Xy + orientation.Yy + orientation.Zy, 
                    center.z - orientation.Xz + orientation.Yz + orientation.Zz );
        glVertex3f( center.x + orientation.Xx + orientation.Yx + orientation.Zx, 
                    center.y + orientation.Xy + orientation.Yy + orientation.Zy, 
                    center.z + orientation.Xz + orientation.Yz + orientation.Zz );
    glEnd();
    
    // Bottom Face
    glBegin( GL_LINES );
        glVertex3f( center.x + orientation.Xx - orientation.Yx - orientation.Zx, 
                    center.y + orientation.Xy - orientation.Yy - orientation.Zy, 
                    center.z + orientation.Xz - orientation.Yz - orientation.Zz );
        glVertex3f( center.x + orientation.Xx - orientation.Yx + orientation.Zx, 
                    center.y + orientation.Xy - orientation.Yy + orientation.Zy, 
                    center.z + orientation.Xz - orientation.Yz + orientation.Zz );
        glVertex3f( center.x + orientation.Xx - orientation.Yx + orientation.Zx, 
                    center.y + orientation.Xy - orientation.Yy + orientation.Zy, 
                    center.z + orientation.Xz - orientation.Yz + orientation.Zz );
        glVertex3f( center.x - orientation.Xx - orientation.Yx + orientation.Zx, 
                    center.y - orientation.Xy - orientation.Yy + orientation.Zy, 
                    center.z - orientation.Xz - orientation.Yz + orientation.Zz );
        glVertex3f( center.x - orientation.Xx - orientation.Yx + orientation.Zx, 
                    center.y - orientation.Xy - orientation.Yy + orientation.Zy, 
                    center.z - orientation.Xz - orientation.Yz + orientation.Zz );
        glVertex3f( center.x - orientation.Xx - orientation.Yx - orientation.Zx, 
                    center.y - orientation.Xy - orientation.Yy - orientation.Zy, 
                    center.z - orientation.Xz - orientation.Yz - orientation.Zz );
        glVertex3f( center.x - orientation.Xx - orientation.Yx - orientation.Zx, 
                    center.y - orientation.Xy - orientation.Yy - orientation.Zy, 
                    center.z - orientation.Xz - orientation.Yz - orientation.Zz );
        glVertex3f( center.x + orientation.Xx - orientation.Yx - orientation.Zx, 
                    center.y + orientation.Xy - orientation.Yy - orientation.Zy, 
                    center.z + orientation.Xz - orientation.Yz - orientation.Zz );
    glEnd();
    
    // Left Face
    glBegin( GL_LINES );
        glVertex3f( center.x - orientation.Xx + orientation.Yx + orientation.Zx, 
                    center.y - orientation.Xy + orientation.Yy + orientation.Zy, 
                    center.z - orientation.Xz + orientation.Yz + orientation.Zz );
        glVertex3f( center.x - orientation.Xx + orientation.Yx - orientation.Zx, 
                    center.y - orientation.Xy + orientation.Yy - orientation.Zy, 
                    center.z - orientation.Xz + orientation.Yz - orientation.Zz );
        glVertex3f( center.x - orientation.Xx + orientation.Yx - orientation.Zx, 
                    center.y - orientation.Xy + orientation.Yy - orientation.Zy, 
                    center.z - orientation.Xz + orientation.Yz - orientation.Zz );
        glVertex3f( center.x - orientation.Xx - orientation.Yx - orientation.Zx, 
                    center.y - orientation.Xy - orientation.Yy - orientation.Zy, 
                    center.z - orientation.Xz - orientation.Yz - orientation.Zz );
        glVertex3f( center.x - orientation.Xx - orientation.Yx - orientation.Zx, 
                    center.y - orientation.Xy - orientation.Yy - orientation.Zy, 
                    center.z - orientation.Xz - orientation.Yz - orientation.Zz );
        glVertex3f( center.x - orientation.Xx - orientation.Yx + orientation.Zx, 
                    center.y - orientation.Xy - orientation.Yy + orientation.Zy, 
                    center.z - orientation.Xz - orientation.Yz + orientation.Zz );
        glVertex3f( center.x - orientation.Xx - orientation.Yx + orientation.Zx, 
                    center.y - orientation.Xy - orientation.Yy + orientation.Zy, 
                    center.z - orientation.Xz - orientation.Yz + orientation.Zz );
        glVertex3f( center.x - orientation.Xx + orientation.Yx + orientation.Zx, 
                    center.y - orientation.Xy + orientation.Yy + orientation.Zy, 
                    center.z - orientation.Xz + orientation.Yz + orientation.Zz );
    glEnd();

    // Right Face
    glBegin( GL_LINES );
        glVertex3f( center.x + orientation.Xx + orientation.Yx - orientation.Zx, 
                    center.y + orientation.Xy + orientation.Yy - orientation.Zy, 
                    center.z + orientation.Xz + orientation.Yz - orientation.Zz );
        glVertex3f( center.x + orientation.Xx + orientation.Yx + orientation.Zx, 
                    center.y + orientation.Xy + orientation.Yy + orientation.Zy, 
                    center.z + orientation.Xz + orientation.Yz + orientation.Zz );
        glVertex3f( center.x + orientation.Xx + orientation.Yx + orientation.Zx, 
                    center.y + orientation.Xy + orientation.Yy + orientation.Zy, 
                    center.z + orientation.Xz + orientation.Yz + orientation.Zz );
        glVertex3f( center.x + orientation.Xx - orientation.Yx + orientation.Zx, 
                    center.y + orientation.Xy - orientation.Yy + orientation.Zy, 
                    center.z + orientation.Xz - orientation.Yz + orientation.Zz );
        glVertex3f( center.x + orientation.Xx - orientation.Yx + orientation.Zx, 
                    center.y + orientation.Xy - orientation.Yy + orientation.Zy, 
                    center.z + orientation.Xz - orientation.Yz + orientation.Zz );
        glVertex3f( center.x + orientation.Xx - orientation.Yx - orientation.Zx, 
                    center.y + orientation.Xy - orientation.Yy - orientation.Zy, 
                    center.z + orientation.Xz - orientation.Yz - orientation.Zz );
        glVertex3f( center.x + orientation.Xx - orientation.Yx - orientation.Zx, 
                    center.y + orientation.Xy - orientation.Yy - orientation.Zy, 
                    center.z + orientation.Xz - orientation.Yz - orientation.Zz ); 
        glVertex3f( center.x + orientation.Xx + orientation.Yx - orientation.Zx, 
                    center.y + orientation.Xy + orientation.Yy - orientation.Zy, 
                    center.z + orientation.Xz + orientation.Yz - orientation.Zz );
    glEnd();
    // End of draw wireframe rectangle 
 }
 
 template <typename TYPENAME>
 inline void Render_Shape::Box_WireFrame( const Vector3<TYPENAME>& center, 
                                 const TYPENAME& half_width, const TYPENAME& half_height, const TYPENAME& half_depth,
                                 TYPENAME Xx, TYPENAME Yx, TYPENAME Zx,
                                 TYPENAME Xy, TYPENAME Yy, TYPENAME Zy,
                                 TYPENAME Xz, TYPENAME Yz, TYPENAME Zz )
 {
    Xx *= half_width;
    Xy *= half_width;
    Xz *= half_width;
    Yx *= half_height;
    Yy *= half_height;
    Yz *= half_height;
    Zx *= half_depth;
    Zy *= half_depth;
    Zz *= half_depth;
    
    Vector3<TYPENAME> front_top_left( center.x + Zx + Yx - Xx, center.y + Zy + Yy - Xy, center.z + Zz + Yz - Xz );
    Vector3<TYPENAME> front_top_right( center.x + Zx + Yx + Xx, center.y + Zy + Yy + Xy, center.z + Zz + Yz + Xz );
    Vector3<TYPENAME> front_bottom_left( center.x + Zx - Yx - Xx, center.y + Zy - Yy - Xy, center.z + Zz - Yz - Xz );
    Vector3<TYPENAME> front_bottom_right( center.x + Zx - Yx + Xx, center.y + Zy - Yy + Xy, center.z + Zz - Yz + Xz );
    Vector3<TYPENAME> back_top_left( center.x - Zx + Yx - Xx, center.y - Zy + Yy - Xy, center.z - Zz + Yz - Xz );
    Vector3<TYPENAME> back_top_right( center.x - Zx + Yx + Xx, center.y - Zy + Yy + Xy, center.z - Zz + Yz + Xz );
    Vector3<TYPENAME> back_bottom_left( center.x - Zx - Yx - Xx, center.y - Zy - Yy - Xy, center.z - Zz - Yz - Xz );
    Vector3<TYPENAME> back_bottom_right( center.x - Zx - Yx + Xx, center.y - Zy - Yy + Xy, center.z - Zz - Yz + Xz );
    
    // Draw wireframe box
    
    glBegin( GL_LINES );
    // Front Face
        glVertex3f( front_top_left.x, front_top_left.y, front_top_left.z );
        glVertex3f( front_top_right.x, front_top_right.y, front_top_right.z );
        
        glVertex3f( front_top_right.x, front_top_right.y, front_top_right.z );
        glVertex3f( front_bottom_right.x, front_bottom_right.y, front_bottom_right.z );
        
        glVertex3f( front_bottom_right.x, front_bottom_right.y, front_bottom_right.z );
        glVertex3f( front_bottom_left.x, front_bottom_left.y, front_bottom_left.z );
        
        glVertex3f( front_bottom_left.x, front_bottom_left.y, front_bottom_left.z );
        glVertex3f( front_top_left.x, front_top_left.y, front_top_left.z );
    
    // Back Face
        glVertex3f( back_top_left.x, back_top_left.y, back_top_left.z );
        glVertex3f( back_top_right.x, back_top_right.y, back_top_right.z );
        
        glVertex3f( back_top_right.x, back_top_right.y, back_top_right.z );
        glVertex3f( back_bottom_right.x, back_bottom_right.y, back_bottom_right.z );
        
        glVertex3f( back_bottom_right.x, back_bottom_right.y, back_bottom_right.z );
        glVertex3f( back_bottom_left.x, back_bottom_left.y, back_bottom_left.z );
        
        glVertex3f( back_bottom_left.x, back_bottom_left.y, back_bottom_left.z );
        glVertex3f( back_top_left.x, back_top_left.y, back_top_left.z );
        
    // Two lines on Left Face 
        glVertex3f( back_top_left.x, back_top_left.y, back_top_left.z );
        glVertex3f( front_top_left.x, front_top_left.y, front_top_left.z );
        
        glVertex3f( back_bottom_left.x, back_bottom_left.y, back_bottom_left.z );
        glVertex3f( front_bottom_left.x, front_bottom_left.y, front_bottom_left.z );
        
    // Two lines on Right Face
        glVertex3f( back_top_right.x, back_top_right.y, back_top_right.z );
        glVertex3f( front_top_right.x, front_top_right.y, front_top_right.z );
        
        glVertex3f( back_bottom_right.x, back_bottom_right.y, back_bottom_right.z );
        glVertex3f( front_bottom_right.x, front_bottom_right.y, front_bottom_right.z );
    glEnd();
    
    // End of draw wireframe rectangle 
 }
 
 /**
  * Sphere_WireFrame() renders a wire frame sphere given the center and radius of the sphere.
  *
  * @param (const Vector3<TYPENAME>&) center
  * @param (const TYPENAME) radius
  */
 template <typename TYPENAME>
 inline void Render_Shape::Sphere_WireFrame( const Vector3<TYPENAME>& center, const TYPENAME radius )
 {
    glPushMatrix();
        glTranslatef( center.x, center.y, center.z );
        glutWireSphere( radius, 50, 15 );
    glPopMatrix();
 }
 
 #endif // RENDER_SHAPE_H